﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Windows.Forms;
using Microsoft.WindowsServerSolutions.Administration.ObjectModel;
using Microsoft.WindowsServerSolutions.Administration.ObjectModel.ComponentServices;
using TV4Home.Server.TVEInteractionLibrary.Interfaces;
using TV4Home.Server.Vail.AddIn.SchedulesAndRecordings;

namespace TV4Home.Server.Vail.AddIn
{
    public class SchedulesAndRecordingsSubTabPage : Page
    {
        public SchedulesAndRecordingsSubTabPage()
            : base(new Guid("B64BFD7A-79A7-4CBF-AC4F-F9566DE12840"),
            "Schedules / Recordings",
            "View schedules and recordings.")
        {
        }

        protected override PageContent CreateContent()
        {
            return PageContent.Create<MyBusinessObject>(
               new SubTabListProvider(this),
               SubTabListColumns.CreateColumns(),
               SubTabListGroupings.CreateGroupings(),
               SubTabTasks.CreateTasks(),
               SubTabDetails.GetDetails
            );
        }
    }

    namespace SchedulesAndRecordings
    {
        public class MyBusinessObject
        {
            public MyBusinessObject(object item)
            {
                this.Item = item;
            }

            private object Item { get; set; }

            public WebSchedule Schedule { get { return this.Item as WebSchedule; } }
            public WebRecording Recording { get { return this.Item as WebRecording; } }

            public bool IsWebSchedule
            {
                get { return this.Item is WebSchedule; }
            }

            public bool IsWebRecording
            {
                get { return this.Item is WebRecording; }
            }
        }

        public class SubTabListProvider : ListProvider<MyBusinessObject>
        {
            ITVEInteraction wcfChannel = null;

            public SubTabListProvider(IServiceProvider serviceProvider)
            {
                SubTabTasks.serviceProvider = serviceProvider;
            }

            protected override void RefreshAndListenForUpdates(IList<MyBusinessObject> list)
            {
                try
                {
                    this.Errors.Reset();

                    if (wcfChannel == null)
                        wcfChannel = ChannelFactory<ITVEInteraction>.CreateChannel(new NetNamedPipeBinding() { MaxReceivedMessageSize = 10000000 }, new EndpointAddress("net.pipe://localhost/TV4Home.Server.CoreService/TVEInteractionService"));

                    foreach (WebSchedule schedule in wcfChannel.GetSchedules())
                    {
                        list.Add(new MyBusinessObject(schedule));
                    }

                    foreach (WebRecording recording in wcfChannel.GetRecordings())
                    {
                        list.Add(new MyBusinessObject(recording));
                    }
                }
                catch (Exception ex)
                {
                    this.Errors.Report(new ErrorInfo("Couldn't retrieve data.", ex));

                    if (ex.InnerException != null)
                        this.Errors.Report(new ErrorInfo("InnerException", ex.InnerException));

                    wcfChannel = null;
                }
            }

            protected override void StopListeningForUpdates()
            {

            }

            protected override string GetObjectDisplayName(MyBusinessObject businessObj)
            {
                return businessObj.IsWebSchedule ? businessObj.Schedule.ProgramName : businessObj.Recording.FileName;
            }

            protected override string GetObjectId(MyBusinessObject businessObj)
            {
                return businessObj.IsWebSchedule ? businessObj.Schedule.IdSchedule.ToString() : businessObj.Recording.IdRecording.ToString();
            }
        }

        static class SubTabListColumns
        {
            public static ListColumnCollection<MyBusinessObject> CreateColumns()
            {
                return new ListColumnCollection<MyBusinessObject>()
                           {
                               new ListColumn<MyBusinessObject>("Name", x => x.IsWebSchedule ? x.Schedule.ProgramName : x.Recording.FileName) {IsRequired = true}
                           };
            }
        }

        static class SubTabListGroupings
        {
            public static ListGroupingCollection<MyBusinessObject> CreateGroupings()
            {
                ListGroupingCollection<MyBusinessObject> groupCollection =
                    new ListGroupingCollection<MyBusinessObject>
                        {
                            new ListGrouping<MyBusinessObject>("Schedules / Recordings", x => x.IsWebSchedule ? new ListGroup<MyBusinessObject>("Scheduled programs") : new ListGroup<MyBusinessObject>("Recorded programs"))
                        };

                groupCollection.DefaultGrouping = groupCollection.First<ListGrouping<MyBusinessObject>>();

                return groupCollection;
            }
        }

        static class SubTabTasks
        {
            public static IServiceProvider serviceProvider;

            public static TaskCollection CreateTasks()
            {
                return new TaskCollection
                           {
                               RefreshTask()
                           };
            }

            private static AsyncUiTask RefreshTask()
            {
                return new AsyncUiTask("Refresh", sender =>
                {
                    DoRefresh();
                    return null;
                });
            }

            private static void DoRefresh()
            {
                if (serviceProvider == null)
                    return;

                DataRefresher service = serviceProvider.GetService(typeof(DataRefresher)) as DataRefresher;

                if (service != null)
                    service.Refresh();
            }
        }

        static class SubTabDetails
        {
            public static DateTime DateTimeMin = new DateTime(2000, 1, 1);

            public static DetailColumnCollection GetDetails(MyBusinessObject businessObj)
            {
                DetailColumnCollection columns = new DetailColumnCollection();
                DetailColumn column = new DetailColumn();

                DetailGroup group = null;

                if (businessObj.IsWebSchedule)
                {
                    group = new DetailGroup("Schedule Information")
                                {
                                    {"Program Name", businessObj.Schedule.ProgramName},
                                    {"Start Time", businessObj.Schedule.StartTime != DateTimeMin ? businessObj.Schedule.StartTime.ToString() : ""},
                                    {"End Time", businessObj.Schedule.EndTime != DateTimeMin ? businessObj.Schedule.EndTime.ToString() : ""},
                                    {"Series", businessObj.Schedule.Series.ToString()},
                                    {"Pre Record Interval", businessObj.Schedule.PreRecordInterval.ToString()},
                                    {"Post Record Interval", businessObj.Schedule.PostRecordInterval.ToString()},
                                    {"Directory", businessObj.Schedule.Directory}
                                };
                }
                else
                {
                    group = new DetailGroup("Recording Information")
                                {
                                    {"Title", businessObj.Recording.Title},
                                    {"Description", businessObj.Recording.Description},
                                    {"Start Time", businessObj.Recording.StartTime != DateTimeMin ? businessObj.Recording.StartTime.ToString() : ""},
                                    {"End Time", businessObj.Recording.EndTime != DateTimeMin ? businessObj.Recording.EndTime.ToString() : ""},
                                    {"Recording File", businessObj.Recording.FileName},
                                    {"Times Watched", businessObj.Recording.TimesWatched.ToString()},
                                    {"Keep until", businessObj.Recording.KeepUntilDate != DateTimeMin ? businessObj.Recording.KeepUntilDate.ToString() : ""}
                                };
                }

                column.Add(group);
                columns.Add(column);

                return columns;
            }
        }
    }
}